import axios, {AxiosInstance, InternalAxiosRequestConfig, AxiosResponse, AxiosRequestConfig} from 'axios'
import {ElMessage} from 'element-plus'
import {useUserAuthStore} from '@/store/modules/auth/index.ts'
import type {Result} from './type'
//axios配置项
const config = {
    baseURL: '/api',  //接口请求地址
    timeout: 10000
}

class Http {
    //axios的实例
    private instance: AxiosInstance;

    // 初始化
    constructor(configs: AxiosRequestConfig) {
        // 创建axios的实例
        this.instance = axios.create(configs)
        // 配置拦截器
        this.interceptors()
    }

    // 请求发送、返回之后做处理
    private interceptors() {
        // 请求发送之前的处理：请求头携带token
        this.instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
            // 获取用户相关的小仓库:获取仓库内部token，登录成功以后挈带给服务器
            let userAuthStore = useUserAuthStore()
            // 获取token
            let token = userAuthStore.token;
            if (token && config) {
               config.headers[`saToken`] = token
            }
            return config
        }, (error: any) => {
            error.data = {}
            error.data.msg = '服务器异常'
            return Promise.reject(error)
        })
        // 请求返回之后的处理
        this.instance.interceptors.response.use((res: AxiosResponse) => {
            // 如果是blob类型，直接返回
            if (res.config.responseType === 'blob') {
                return res;
            }
            
            if (res.data.code == 200) {
                return res.data
            } else {
                ElMessage.error(res.data.message || '后端服务器异常')
                return Promise.reject(res.data.message || '后端服务器异常')
            }
        }, (error: any) => {
            console.log("响应拦截器进入错误")
            error.data = {};
            if (error && error.response) {
                switch (error.response.status) {
                    case 400:
                        error.data.msg = '请求错误(400)'
                        ElMessage.error(error.data.msg)
                        break;
                    case 401:
                        error.data.msg = '未授权，请登录(401)'
                        ElMessage.error(error.data.msg)
                        break;
                    case 403:
                        error.data.msg = '拒绝访问(403)'
                        ElMessage.error(error.data.msg)
                        break;
                    case 404:
                        error.data.msg = '请求出错(404)'
                        ElMessage.error(error.data.msg)
                        break;
                    case 408:
                        error.data.msg = '请求超时(408)'
                        ElMessage.error(error.data.msg)
                        break;
                    case 500:
                        error.data.msg = '服务器错误(500)'
                        ElMessage.error(error.data.msg)
                        break;
                    default:
                        error.data.msg = `连接出错(${error.response.status})`
                        ElMessage.error(error.data.msg)
                }
            } else {
                error.data.msg = '连接服务器失败'
                ElMessage.error(error.data.msg)
            }
            return Promise.reject(error)
        })
    }

    // post请求
    post<T = Result>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> {
        return this.instance.post(url, data, config)
    }

    // put请求
    put<T = Result>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> {
        return this.instance.put(url, data, config)
    }

    // get请求
    get<T = Result>(url: string, params?: object, config?: AxiosRequestConfig): Promise<T> {
        return this.instance.get(url, { params, ...config })
    }

    // delete请求
    delete<T = Result>(url: string, params?: object, config?: AxiosRequestConfig): Promise<T> {
        return this.instance.delete(url, { params, ...config })
    }

    // 图片上传
    upload<T = Result>(url: string, params?: object): Promise<T> {
        return this.instance.post(url, params, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        })
    }
}

export default new Http(config)

